package com.yyfax.pay.quartz.adapter.impl;

import javax.annotation.Resource;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Service;

import com.yyfax.commons.lang.DateUtil;
import com.yyfax.framework.common.Log;
import com.yyfax.framework.yyfax.CryptUtil;
import com.yyfax.pay.common.annotation.DepositQueryTaskType;
import com.yyfax.pay.common.enums.FuiouBusiTypeEnum;
import com.yyfax.pay.common.enums.FuiouDepositStateEnum;
import com.yyfax.pay.common.exception.PayExceptionCode;
import com.yyfax.pay.common.model.vo.PayRspCodeVO;
import com.yyfax.pay.depository.dao.FuiouArtificialRegisterDao;
import com.yyfax.pay.depository.domain.FuiouArtificialRegister;
import com.yyfax.pay.depository.domain.FuiouQueryTask;
import com.yyfax.pay.depository.service.inner.FuiouQueryService;
import com.yyfax.pay.depository.service.inner.impl.FuiouDepositRegisterServiceImpl;
import com.yyfax.pay.depository.vo.ArtificialRegisterVO;
import com.yyfax.pay.quartz.adapter.DepositQueryHandlerAdapter;
import com.yyfax.pay.quartz.model.vo.TaskResultVO;
import com.yyfax.pay.third.facade.fuioudeposit.FuiouDepositService;
import com.yyfax.pay.third.model.to.fuioudeposit.xml.UserInfoPlain.UserInfoResult;

/**
 * 法人开户超时查询,订单更新
 *
 * @author liangqm
 * @date 2018-01-12 11:27:18
 * @since v2.0.7
 */
@Service
@DepositQueryTaskType(FuiouBusiTypeEnum.ARTIFICIAL_REGISTER)
public class FuiouArtificialRegisterQueryHandler implements DepositQueryHandlerAdapter {
	private static final Logger logger = LoggerFactory.getLogger(FuiouArtificialRegisterQueryHandler.class);

	@Resource
	private FuiouQueryService queryService;

	@Resource
	private FuiouArtificialRegisterDao artificialRegisterDao;

	@Resource
	private FuiouDepositRegisterServiceImpl registerService;

	@Resource
	private FuiouDepositService fuiouDepositService;

	@Override
	public TaskResultVO handle(FuiouQueryTask task) throws Throwable {
		final String op = "FuiouArtificialRegisterQueryHandler.handle";

		// 查询 法人开户订单
		FuiouArtificialRegister po = artificialRegisterDao.selectByPrimaryKey(task.getBusiId());

		/*
		 * 要命的优化需求，时间赶，暂时没有时间改造旧的企业开户查询策略，将业务逻辑放这里，后期再改造
		 */

		ArtificialRegisterVO vo = ArtificialRegisterVO.newInstance(po);

		if (!vo.isQuery()) {
			return new TaskResultVO(true);
		}

		// step2.如果订单未出结果，则调用富友存管查询用户信息接口
		PayRspCodeVO payRsp = fuiouDepositService.queryUserInfo(po.getBusiId(), po.getMerchantCode(), po.getPhone());

		if (PayExceptionCode.WARN_REQ_TIME_OUT.isCode(payRsp.getCode()) || PayExceptionCode.TO_CONFIRM.isCode(payRsp.getCode())) {
			return new TaskResultVO(false);
		}

		String state = FuiouDepositStateEnum.FAIL.getValue();
		int rspCode = payRsp.getCode();
		String rspMsg = payRsp.getDesc();

		if (PayExceptionCode.SUCCESS.isCode(payRsp.getCode())) {

			UserInfoResult result = (UserInfoResult) payRsp.getObj();
			String cardNo = CryptUtil.decrypt(po.getCardNoCip());
			String idNo = CryptUtil.decrypt(po.getIdNoCip());

			// 在超时的情况下，用户注册存在并发的情况，需要判断 证件号，企业名称，银行卡号一致性，如果不一致，则预警。且不更新数据库
			if (!StringUtils.equals(idNo, result.getIdNo()) || !StringUtils.equals(po.getCustomerName(), result.getAccountName())
					|| !StringUtils.equals(cardNo, result.getCardNo())) {
				logger.error(Log.op(op).msg("【富友存管企业用户查询开户信息】查询开户信息成功，但是返回开户信息不一致，需要人工介入。").kv("UserInfoResult", result).kv("busiId", po.getBusiId())
						.toString());
				rspCode = PayExceptionCode.ERROR_PAY_FAIL.getCode();
				rspMsg = PayExceptionCode.ERROR_PAY_FAIL.getDesc();

			} else {
				// 更新订单处理状态为成功
				state = FuiouDepositStateEnum.SUCCESS.getValue();
				registerService.saveEnterpriseAuth(po.getMerchantCode(), po.getMerchantUserId(), po.getCustomerName(), po.getBankCode(), cardNo);
			}

		}else if(PayExceptionCode.ERROR_NOT_OPEN_ACCOUNT.isCode(payRsp.getCode())){
			//如果响应码为未开户,则初始化订单状态为"初始化"状态,等待业务下一次重调.edit by wangjw since 2.0.8
			state= FuiouDepositStateEnum.INI.getValue();
		}

		artificialRegisterDao.updateStateAndRspByBusiId(state, po.getBusiId(), DateUtil.getCurrentDateTime(), rspCode, rspMsg);

		return new TaskResultVO(true);
	}
}
